package io.wongxd.solution.compose.custom.views.value_selector.date_time_selector

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import io.wongxd.solution.compose.custom.views.value_selector.CenterLines
import io.wongxd.solution.compose.custom.views.value_selector.*
import io.wongxd.solution.compose.custom.views.value_selector.valueSelector_defaultSelectedTextColor
import io.wongxd.solution.compose.custom.views.value_selector.valueSelector_defaultSelectedTextSize
import io.wongxd.solution.compose.custom.views.value_selector.valueSelector_defaultTextColor
import io.wongxd.solution.compose.custom.views.value_selector.valueSelector_defaultTextSize1
import io.wongxd.solution.compose.custom.views.value_selector.valueSelector_defaultTextSize2
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged

/**
 * effect : 日期时间选择器
 *          W Date Time Selector
 *
 * @param state [WDateTimeSelector] 的状态
 *              [WDateTimeSelector]'s state
 * @param modifier 修饰
 * @param isLoop 值列表是否可循环
 *               Whether the value list is loop
 */
@ExperimentalFoundationApi
@Composable
fun WDateTimeSelector(
    state: WDateTimeSelectorState,
    modifier: Modifier = Modifier,
    dateDividerString: Triple<String, String, String> = Triple("", "", ""),
    dateDividerTextStyle: TextStyle = TextStyle.Default,
    dateDividerPadding: Dp = 2.dp,
    isShowDate: Boolean = true,
    isShowTime: Boolean = false,
    isShowSecond: Boolean = false,
    timeDividerString: Triple<String, String, String> = Triple("", "", ""),
    timeDividerTextStyle: TextStyle = dateDividerTextStyle,
    timeDividerPadding: Dp = dateDividerPadding,
    dividerClosest: Boolean = true, // 分隔符紧贴
    isLoop: Boolean = false,
    cacheSize: Int = 2,
    textSizes: ArrayList<TextUnit> = remember {
        arrayListOf(
            valueSelector_defaultTextSize2,
            valueSelector_defaultTextSize1
        )
    },
    selectedTextSize: TextUnit = valueSelector_defaultSelectedTextSize,
    textColors: ArrayList<Color> = remember {
        arrayListOf(
            valueSelector_defaultTextColor,
            valueSelector_defaultTextColor
        )
    },
    selectedTextColor: Color = valueSelector_defaultSelectedTextColor,
    lineColor: Color = defLineColor
) {
    LaunchedEffect(Unit) {
        //处理每月天数变化
        snapshotFlow {
            when (state.getMonth()) {
                "1", "3", "5", "7", "8", "10", "12" -> 31
                "2" -> {
                    //闰年计算
                    val year = state.getYear().toInt()
                    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) 29 else 28
                }

                else -> 30
            }
        }.distinctUntilChanged()
            .collect {
                state.days = (1..it).map(Int::toString).toTypedArray()
            }
    }
    Box(modifier) {

        Row {

            if (isShowDate) {
                Item(
                    values = state.years,
                    state = state.yearState,
                    defaultSelectIndex = remember(state) {
                        state.years.indexOf(state.defaultYear.toString())
                    },
                    isLoop = isLoop,
                    cacheSize = cacheSize,
                    textSizes = textSizes,
                    selectedTextSize = selectedTextSize,
                    textColors = textColors,
                    selectedTextColor = selectedTextColor,
                    dividerClosest = dividerClosest,
                    divider = dateDividerString.first,
                    dividerStyle = dateDividerTextStyle,
                    dividerPadding = dateDividerPadding
                )


                Item(
                    values = state.months,
                    state = state.monthState,
                    defaultSelectIndex = remember(state) {
                        state.months.indexOf(state.defaultMonth.toString())
                    },
                    isLoop = isLoop,
                    cacheSize = cacheSize,
                    textSizes = textSizes,
                    selectedTextSize = selectedTextSize,
                    textColors = textColors,
                    selectedTextColor = selectedTextColor,
                    dividerClosest = dividerClosest,
                    divider = dateDividerString.second,
                    dividerStyle = dateDividerTextStyle,
                    dividerPadding = dateDividerPadding
                )


                Item(
                    values = state.days,
                    state = state.dayState,
                    defaultSelectIndex = remember(state) {
                        state.days.indexOf(state.defaultDay.toString())
                    },
                    isLoop = isLoop,
                    cacheSize = cacheSize,
                    textSizes = textSizes,
                    selectedTextSize = selectedTextSize,
                    textColors = textColors,
                    selectedTextColor = selectedTextColor,
                    dividerClosest = dividerClosest,
                    divider = dateDividerString.third,
                    dividerStyle = dateDividerTextStyle,
                    dividerPadding = dateDividerPadding
                )

            }


            if (isShowTime) {

                Item(
                    values = state.hours,
                    state = state.hourState,
                    defaultSelectIndex = remember(state) {
                        state.hours.indexOf(state.defaultHour.toString())
                    },
                    isLoop = isLoop,
                    cacheSize = cacheSize,
                    textSizes = textSizes,
                    selectedTextSize = selectedTextSize,
                    textColors = textColors,
                    selectedTextColor = selectedTextColor,
                    dividerClosest = dividerClosest,
                    divider = timeDividerString.first,
                    dividerStyle = timeDividerTextStyle,
                    dividerPadding = timeDividerPadding
                )


                Item(
                    values = state.minutes,
                    state = state.minuteState,
                    defaultSelectIndex = remember(state) {
                        state.minutes.indexOf(state.defaultMinute.toString())
                    },
                    isLoop = isLoop,
                    cacheSize = cacheSize,
                    textSizes = textSizes,
                    selectedTextSize = selectedTextSize,
                    textColors = textColors,
                    selectedTextColor = selectedTextColor,
                    dividerClosest = dividerClosest,
                    divider = timeDividerString.second,
                    dividerStyle = timeDividerTextStyle,
                    dividerPadding = timeDividerPadding
                )


                if (isShowSecond) {
                    Item(
                        values = state.seconds,
                        state = state.secondState,
                        defaultSelectIndex = remember(state) {
                            state.seconds.indexOf(state.defaultSecond.toString())
                        },
                        isLoop = isLoop,
                        cacheSize = cacheSize,
                        textSizes = textSizes,
                        selectedTextSize = selectedTextSize,
                        textColors = textColors,
                        selectedTextColor = selectedTextColor,
                        dividerClosest = dividerClosest,
                        divider = timeDividerString.third,
                        dividerStyle = timeDividerTextStyle,
                        dividerPadding = timeDividerPadding
                    )
                }
            }

        }

        CenterLines(lineColor)
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun RowScope.Item(
    values: Array<String>,
    state: WValueSelectState,
    defaultSelectIndex: Int = 0,
    isLoop: Boolean,
    cacheSize: Int,
    textSizes: ArrayList<TextUnit>,
    selectedTextSize: TextUnit,
    textColors: ArrayList<Color>,
    selectedTextColor: Color,
    dividerClosest: Boolean,
    divider: String,
    dividerStyle: TextStyle,
    dividerPadding: Dp,
) {
    if (dividerClosest) {
        WValueSelector(
            values = values,
            state = state,
            defaultSelectIndex = defaultSelectIndex,
            modifier = Modifier.weight(1f),
            dividerPre = " ".repeat((dividerPadding.value / 3.dp.value).toInt()),
            dividerString = divider,
            isLoop = isLoop,
            cacheSize = cacheSize,
            textSizes = textSizes,
            selectedTextSize = selectedTextSize,
            textColors = textColors,
            selectedTextColor = selectedTextColor,
        )
    } else {
        WValueSelector(
            values = values,
            state = state,
            modifier = Modifier.weight(1f),
            defaultSelectIndex = defaultSelectIndex,
            isLoop = isLoop,
            cacheSize = cacheSize,
            textSizes = textSizes,
            selectedTextSize = selectedTextSize,
            textColors = textColors,
            selectedTextColor = selectedTextColor,
        )

        Text(
            text = divider,
            style = dividerStyle,
            modifier = Modifier
                .align(Alignment.CenterVertically)
                .padding(horizontal = dividerPadding)
        )
    }
}